package test.taylor.com.taylorcode.ui.zoom

import android.content.Context
import android.graphics.Matrix
import android.graphics.PointF
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import androidx.appcompat.widget.AppCompatImageView

class TouchImageView : AppCompatImageView {
    var mMatrix: Matrix? = null
    var mode = NONE

    // Remember some things for zooming
    var last = PointF()
    var start = PointF()
    var minScale = 1f
    var maxScale = 3f
    var viewWidth = 0
    var viewHeight = 0
    var saveScale = 1f
    protected var origWidth = 0f
    protected var origHeight = 0f
    var oldMeasuredWidth = 0
    var oldMeasuredHeight = 0
    var mScaleDetector: ScaleGestureDetector? = null

    var initWidth: Int = 0
    var initHeight: Int = 0

    constructor(context: Context) : super(context) {
        sharedConstructing(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        sharedConstructing(context)
    }

    private fun sharedConstructing(context: Context) {
        super.setClickable(true)
        mScaleDetector = ScaleGestureDetector(context, ScaleListener())
        mMatrix = Matrix()
        imageMatrix = mMatrix
        scaleType = ScaleType.MATRIX
        setOnTouchListener { v, event ->
            mScaleDetector!!.onTouchEvent(event)
//            val curr = PointF(event.x, event.y)
//            when (event.action) {
//                MotionEvent.ACTION_DOWN -> {
//                    last.set(curr)
//                    start.set(last)
//                    mode = DRAG
//                }
//                MotionEvent.ACTION_MOVE -> if (mode == DRAG) {
//                    val deltaX = curr.x - last.x
//                    val deltaY = curr.y - last.y
//                    val fixTransX = getFixDragTrans(deltaX, viewWidth.toFloat(), origWidth * saveScale)
//                    val fixTransY = getFixDragTrans(deltaY, viewHeight.toFloat(), origHeight * saveScale)
//                    mMatrix!!.postTranslate(fixTransX, fixTransY)
//                    fixTrans()
//                    last[curr.x] = curr.y
//                }
//                MotionEvent.ACTION_UP -> {
//                    mode = NONE
//                    val xDiff = Math.abs(curr.x - start.x).toInt()
//                    val yDiff = Math.abs(curr.y - start.y).toInt()
//                    if (xDiff < CLICK && yDiff < CLICK) performClick()
//                }
//                MotionEvent.ACTION_POINTER_UP -> mode = NONE
//            }
//            imageMatrix = mMatrix
//            invalidate()
            true // indicate event was handled
        }
    }
//
//    fun setMaxZoom(x: Float) {
//        maxScale = x
//    }

    private inner class ScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener() {
        override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
            mode = ZOOM
            return true
        }

        override fun onScale(detector: ScaleGestureDetector): Boolean {
            var mScaleFactor = detector.scaleFactor
            val origScale = saveScale
            saveScale *= mScaleFactor
            if (saveScale > maxScale) {
                saveScale = maxScale
                mScaleFactor = maxScale / origScale
            } else if (saveScale < minScale) {
                saveScale = minScale
                mScaleFactor = minScale / origScale
            }
            if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight) {
                imageMatrix = Matrix(imageMatrix).apply {
                    postScale(
                        mScaleFactor,
                        mScaleFactor,
                        (viewWidth / 2).toFloat(),
                        (viewHeight / 2).toFloat()
                    )
                }
                Log.v("ttaylor", "onScale1() scale=$mScaleFactor, px=${(viewWidth / 2).toFloat()},py=${(viewHeight / 2).toFloat()}")
            } else {
                mMatrix!!.postScale(mScaleFactor, mScaleFactor, detector.focusX, detector.focusY)
                Log.v("ttaylor", "onScale2() scale=$mScaleFactor, px=${detector.focusX},py=${detector.focusY}")
            }
//            fixTrans()
            return true
        }
    }

//    fun fixTrans() {
//        mMatrix!!.getValues(m)
//        val transX = m[Matrix.MTRANS_X]
//        val transY = m[Matrix.MTRANS_Y]
//        val fixTransX = getFixTrans(transX, viewWidth.toFloat(), origWidth * saveScale)
//        val fixTransY = getFixTrans(transY, viewHeight.toFloat(), origHeight * saveScale)
//        if (fixTransX != 0f || fixTransY != 0f) mMatrix!!.postTranslate(fixTransX, fixTransY)
//    }
//
//    fun getFixTrans(trans: Float, viewSize: Float, contentSize: Float): Float {
//        val minTrans: Float
//        val maxTrans: Float
//        if (contentSize <= viewSize) {
//            minTrans = 0f
//            maxTrans = viewSize - contentSize
//        } else {
//            minTrans = viewSize - contentSize
//            maxTrans = 0f
//        }
//        if (trans < minTrans) return -trans + minTrans
//        return if (trans > maxTrans) -trans + maxTrans else 0f
//    }
//
//    fun getFixDragTrans(delta: Float, viewSize: Float, contentSize: Float): Float {
//        return if (contentSize <= viewSize) {
//            0f
//        } else delta
//    }

//    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
//        viewWidth = MeasureSpec.getSize(widthMeasureSpec)
//        viewHeight = MeasureSpec.getSize(heightMeasureSpec)
//        if (initWidth == 0) initWidth = viewWidth
//        if (initHeight == 0) initHeight = viewHeight
//        //
//        // Rescales image on rotation
//        //
//        if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight || viewWidth == 0 || viewHeight == 0) return
//        oldMeasuredHeight = viewHeight
//        oldMeasuredWidth = viewWidth
//        if (saveScale == 1f) {
//            //Fit to screen.
//            val scale: Float
//            val drawable = drawable
//            if (drawable == null || drawable.intrinsicWidth == 0 || drawable.intrinsicHeight == 0) return
//            val bmWidth = drawable.intrinsicWidth
//            val bmHeight = drawable.intrinsicHeight
//            val scaleX = initWidth.toFloat() / bmWidth.toFloat()
//            val scaleY = initHeight.toFloat() / bmHeight.toFloat()
//            scale = Math.min(scaleX, scaleY)
//            mMatrix!!.setScale(scale, scale)
//            Log.v("ttaylor","onMeasure() mw=${viewWidth}, mh=${viewHeight}, bmpWidth=$bmWidth, bmpHeight=$bmHeight, scaleX=$scaleX, scaleY=$scaleY")
//            // Center the image
//            var redundantYSpace = viewHeight.toFloat() - scale * bmHeight.toFloat()
//            var redundantXSpace = viewWidth.toFloat() - scale * bmWidth.toFloat()
//            redundantYSpace /= 2.toFloat()
//            redundantXSpace /= 2.toFloat()
//            mMatrix!!.postTranslate(redundantXSpace, redundantYSpace)
//            origWidth = viewWidth - 2 * redundantXSpace
//            origHeight = viewHeight - 2 * redundantYSpace
//            imageMatrix = mMatrix
//        }
////        fixTrans()
//    }

    companion object {
        // We can be in one of these 3 states
        const val NONE = 0
        const val DRAG = 1
        const val ZOOM = 2
        const val CLICK = 3
    }
}